package com.tank.jdk8;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * lamabda parameter -> expression body
 * Created with IntelliJ IDEA.
 * User: SuQiEr
 * Date:2016/12/28
 * Time: 17:54
 * To change this template use File | Settings | File Templates.
 */
@Slf4j
public class Java8Tester {

    /**
     * jdk 8 和 jdk 8以下版本 集合排序方法使用
     */
    @Test
    public void testCollections(){
        List<String> names1 = new ArrayList<String>();
        names1.add("Mahesh ");
        names1.add("Suresh ");
        names1.add("Ramesh ");
        names1.add("Naresh ");
        names1.add("Kalpesh ");

        List<String> names2 = new ArrayList<String>();
        names2.add("Mahesh ");
        names2.add("Suresh ");
        names2.add("Ramesh ");
        names2.add("Naresh ");
        names2.add("Kalpesh ");

        Java8Tester tester = new Java8Tester();
        System.out.println("Sort using Java 7 syntax: ");

        tester.sortUsingJava7(names1);
        System.out.println(names1);
        System.out.println("Sort using Java 8 syntax: ");

        tester.sortUsingJava8(names2);
        System.out.println(names2);
    }



    private void sortUsingJava7(List<String> names){
        //sort using java 7
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return s1.compareTo(s2);
            }
        });
    }

    private void sortUsingJava8(List<String> names){
        //sort using java 8
        Collections.sort(names, (s1, s2) -> s1.compareTo(s2));
    }

    @Test
    public void testFunctionInterface(){

        //未使用lambda
      int operate = operate(2, 3, new MathOperation() {

            @Override
            public int operation(int a, int b) {
                return a + b;
            }
        });
      log.info("未使用lambda operate：{}",operate);

        //使用lambda
        operate = operate(2,3,(a, b) -> a+b);
        log.info("使用lambda operate：{}",operate);
        //MathOperation接口实例对象 表达式返回的对象
        MathOperation mathOperation = (a, b) -> a+b;
        //class:com.baofu.depository.jdk8.Java8Tester$$Lambda$2/2042495840
        log.info("该类的类型 class:{}",mathOperation.getClass().getCanonicalName());
        //该类的类型 superClass:java.lang.Object
        log.info("该类的类型 superClass:{}",mathOperation.getClass().getSuperclass().getCanonicalName());
        //该类的实现接口类型 superClass:interface com.baofu.depository.jdk8.Java8Tester$MathOperation
        log.info("该类的实现接口类型 superClass:{}",mathOperation.getClass().getInterfaces()[0]);
    }

    interface  MathOperation{
        int operation(int a,int b);
    }

    interface  GreetingService{

        void sayMessage(String message);

    }

    private int operate(int a, int b, MathOperation mathOperation){
        return mathOperation.operation(a, b);
    }

    final static String salutation = "Hello! ";
    @Test
    public void testSayMessage(){
        GreetingService greetService1 = message ->
                System.out.println(salutation + message);
        greetService1.sayMessage("Mahesh");
        greetService1.sayMessage("你妹");
    }

    //方法引用测试
    @Test
    public void testMethodReferences(){
        List<String> names = new ArrayList<String>();

        names.add("Mahesh");
        names.add("Suresh");
        names.add("Ramesh");
        names.add("Naresh");
        names.add("Kalpesh");
//        Static methods
//        Instance methods
//        Constructors using new operator
        names.forEach(new Consumer() {
            @Override
            public void accept(Object o) {
                log.info("未使用表达式"+o.toString());
            }
        });
        // :: == Consumer
        names.forEach(log::info);
    }
    //测试判断表达式
    @Test
    public void testFunctionInterface2(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        System.out.println("Print all numbers:");
        //pass n as parameter
        eavl(list, n -> true);
        System.out.println("Print even numbers:");
        eavl(list,n ->  n%2 == 0);

        System.out.println("Print numbers greater than 3:");
        eavl(list, n -> n > 3);
    }

    public static void eavl(List<Integer> list, Predicate<Integer> predicate){
        for(Integer n: list) {
            if(predicate.test(n)) {
                System.out.println(n + " ");
            }
        }
    }

    @Test
    public void testInterfaceDefaultMethod(){
            new Man().sayHello();
    }

    interface  Chinese{
        default  void sayHello(){
            log.info("我是中国人");
        }
    }

    interface People{

        default void sayHello(){
            log.info("我是人类");
        }

        static void sayNo(){
            log.info("愚蠢的人类");
        }
    }

    class Man implements Chinese,People{

        @Override
        public void sayHello() {
            People.sayNo();
            People.super.sayHello();
            Chinese.super.sayHello();
            log.info("我是男人");
        }
    }
}

